package com.vito.act.tool;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;

import com.vito.base.util.JSONUtil;
import com.vito.base.util.SpringApplicationContext;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.oa.act.constant.OaActContants;
import com.vito.oa.act.dao.OaActApproverMapper;
import com.vito.oa.act.dao.OaActProcessMapper;
import com.vito.oa.act.event.service.ActivitiEvent;
import com.vito.oa.act.event.service.OaActEventPublisherService;
import com.vito.oa.act.extend.service.OaActExMsgService;

/**
 *整个流程启动监听
 */
public class ActivitiExecutionStartListener implements Serializable, ExecutionListener {
	/**
	 */
	private static final long serialVersionUID = -1534928203372109726L;
	@Override
	public void notify(DelegateExecution execution) throws Exception {
		OaActApproverMapper oaActApproverMapper =SpringApplicationContext.getApplicationContext().getBean(OaActApproverMapper.class);
		
		ExecutionEntity entity = (ExecutionEntity) execution;
		ProcessDefinitionImpl impl = entity.getProcessDefinition();
		String processkey = entity.getProcessDefinition().getKey();
		String businessId = execution.getProcessBusinessKey();
		String startUserId = String.valueOf(entity.getVariable(OaActContants.START_USER));
		//初始化实例终止数量（并签流程有效，作用在销毁多实例的表达式中）
		entity.setVariable(OaActContants.VARIABLES_END_INSTANCES, 0);
		
		List<Map<String,String>> nodeInfo = oaActApproverMapper.queryProcessInfo(impl.getKey(), execution.getProcessBusinessKey());
		if(nodeInfo == null || nodeInfo.isEmpty()){
			return;
		}
		List<ActivityImpl> act =impl.getActivities();
		for(ActivityImpl temp :act){
			if(ActivitiContants.ACTIVITI_TYPE_USERTASK.equals(temp.getProperty(ActivitiContants.ACTIVITI_TYPE))){
				TaskDefinition taskDef = (TaskDefinition) temp.getProperty("taskDefinition");
				int definedAssign = getMaxApprover(taskDef);
				if(definedAssign == 0){
					return;
				}
				String expressionText =  taskDef.getAssigneeExpression().getExpressionText();
				if(expressionText.startsWith("${") && expressionText.endsWith("}")){
					String Assign = expressionText.substring(2, expressionText.length()-1);
					for(int i = 0;i<nodeInfo.size();i++){
						Map<String,String> node = nodeInfo.get(i);
						if(null == node || Validata.isNullOrEmpty(node.get("USERID"))){
							nodeInfo.remove(i);
							continue;
						}
						if(taskDef.getKey().equals(node.get("NODEID"))){
							Object[] users =  node.get("USERID").split(OaActContants.SEPARATOR);
							if(definedAssign == 1){
								entity.setVariable(Assign, users[0]);
							}else{
								entity.setVariable(OaActContants.MUTIL_ASSIGN, Arrays.asList(users));
							}
							nodeInfo.remove(i);
							break;
						}
					}
				}
				
			}
		}
		//根据流程key检查是否需要发消息
		OaActProcessMapper processMapper = SpringApplicationContext.getApplicationContextBean(OaActProcessMapper.class);
		String syskey = processMapper.queryOriginalProcessKey(processkey);
		if(Validata.isNullOrEmpty(syskey)){
			syskey = processkey;
		}
		if(ActivitiEvent.START_EVENT_KEY.contains(syskey)){
			this.sendMessage(businessId, syskey,processkey,"0");
		}
		
		//消息推送给抄送人
		String[] ccUser = (String[])entity.getVariable(OaActContants.COPY_USER);
		OaActExMsgService actExMsgService = SpringApplicationContext.getApplicationContext()
				.getBean(OaActExMsgService.class);
		actExMsgService.sendActMsgToCCuser(startUserId, processkey, businessId,ccUser);
		
		/*
		 * 开始节点跳过审批人为空的节点 
		 */
		OaActivitiTool.jumpToNextAvailableTask(entity, entity.getActivity());
		//entity.setVariable(OaActContants.ORIGIN_TRANSITION, originInfoMap);
		
	}
	private void sendMessage(String businessId,String sysKey,String processkey,String status){
		if(StringUtil.isEmpty(businessId) || StringUtil.isEmpty(processkey)){
			return;
		}
		OaActEventPublisherService publishService = SpringApplicationContext.getApplicationContextBean(OaActEventPublisherService.class);
		publishService.sendActEvent(businessId,sysKey,processkey,status);	
	}
	private int getMaxApprover(TaskDefinition task){
		Expression document = task.getDescriptionExpression();
		int maxApprover = 1;
		if(document != null){
			Map documentation = JSONUtil.convertString2Map(document.getExpressionText());
			if(documentation.containsKey("maxApprover")){
				maxApprover = (int)documentation.get("maxApprover");
			}
		}
		return maxApprover;
	}
}



